#include "openmove_Prefix.h"
#include "SceneBase.h"
#include "OgreEngine.h"
#include "ExampleFrameListener.h"
#include "SkeletalAnimationFrameListener.h"
#include "OgreExternalTextureSourceManager.h"
#include "OgreExternalTextureSource.h"
#include "SceneRencontre.h"
#include "SimpleFrameListener.h"
#include "OgreWireBoundingBox.h"

CSceneRencontre :: CSceneRencontre(COgreEngine &Creator, const String & Name, const int pos) : CSceneBase(Creator, Name, pos), m_pPluie(NULL), m_pPluieTop(NULL), m_Play(false), m_CamFrame(0), m_CloneFrame(0), m_CurrentSpeed(0), m_LastTime(-1)
{
}

CSceneRencontre :: ~CSceneRencontre(void)
{
}

void CSceneRencontre :: Create(TCreatorEntities const &CreatorEntities, TCreatorNodes const &CreatorNodes, TCreatorLights const &CreatorLights, ENetConfig IsClient, Vector3 &CameraStartPos)
{
	CSceneBase::Create(CreatorEntities, CreatorNodes, CreatorLights, IsClient, CameraStartPos);

	AddSpotlight("RencontrespotLight1", 
		Vector3(284.2, 441.6, 76.6),
		-43.9, 70.4, 0, false
		);

	AddSpotlight("RencontrespotLight2", 
		Vector3(115.5, 431.2, 267.3),
		-51, -14, 0, false
		);

	AddSpotlight("RencontrespotLight3", 
		Vector3(-496.6, 598.9, 239.1),
		-50.4, -46.8, 0, true
		);

	AddSpotlight("RencontrespotLight4", 
		Vector3(-680.4, 745, 1361.9),
		-59.4, -29.2, 0, false
		);


	/*
	AddSpotlight("RencontrespotLight1", 
		Vector3(169.0101, 370.0179, -026.3710),
		-67.200058, -96.800087, 0, true
		);

	AddSpotlight("RencontrespotLight2", 
		Vector3(024.9903, 363.1995, -293.1003),
		-82.200073, -68.000061, 0, true
		);

	AddSpotlight("RencontrespotLight3", 
		Vector3(070.9345, 338.6815, -018.2585),
		-61.200054, 21.200018, 0, true
		);

	AddSpotlight("RencontrespotLight4", 
		Vector3(153.9600, 372.8673, -284.0438),
		-57.600052, -66.800056, 0, true
		);

	AddSpotlight("RencontrespotLight5", 
		Vector3(202.2690, 308.4274, 135.6411),
		-52.800045, -70.000061, 0, true
		);

	AddSpotlight("RencontrespotLight6", 
		Vector3(-407.9143, 319.3104, 039.3623),
		-60.600052, -43.200039, 0, false
		);

	AddSpotlight("RencontrespotLight7", 
		Vector3(-179.1897, 373.2876, -060.3434),
		-85.200073, 96.800087, 0, true
		);

	AddSpotlight("RencontrespotLight8", 
		Vector3(-021.6299, 376.4507, -259.0789),
		-57.600052, -66.800056, 0, true
		);

	AddSpotlight("RencontrespotLight9", 
		Vector3(051.5795, 306.6047, 051.8318),
		-61.200054, 21.200018, 0, true
		);

	AddSpotlight("RencontrespotLight10", 
		Vector3(939.8096, 621.1230, -303.0137),
		-59.400051, 5.600005, 0, false
		);

	AddSpotlight("RencontrespotLight11", 
		Vector3(1122.0570, 606.7708, 708.3506),
		-63.600056, 24.800022, 0, false
		);
	
	AddSpotlight("RencontrespotLight12", 
		Vector3(204.6491, 664.6538, 457.8334),
		-61.200054, -180.800156, 0, false
		);

	AddSpotlight("RencontrespotLight13", 
		Vector3(-169.2514, 729.0544, 318.6765),
		-71.400063, -200.800171, 0, false
		);

	AddSpotlight("RencontrespotLight14", 
		Vector3(-203.1956, 800.7999, 224.6474),
		-40.800037, -198.400177, 0, false
		);
	*/

	//m_Compositors.push_back("HDR");
}

void CSceneRencontre :: AddSpotlight(String const &name, Vector3 const &position, Real const &xAngle, Real const &yAngle, Real const &zAngle, bool const CastShadow)
{
	SceneLight light;
	light.m_Name = name;
	light.setType(Light::LT_SPOTLIGHT);
	//light.setDiffuseColour(0.533000, 0.827132, 1.000000);
	light.setDiffuseColour(0.25, 0.25, 0.25);
	light.setCastShadows(CastShadow);
	light.setAttenuation(1000, 1, 0.005, 0);
	light.setSpotlightInnerAngle(Degree(50.0));
	light.setSpotlightOuterAngle(Degree(55.0));
	light.setSpotlightFalloff(1);

	Vector3 vec = -Vector3::UNIT_Z;
	Quaternion rot = Quaternion(Degree(zAngle), Vector3(0, 0, 1)) * Quaternion(Degree(yAngle), Vector3(0, 1, 0)) * Quaternion(Degree(xAngle), Vector3(1, 0, 0));
	Matrix3 rotMat;
	rot.ToRotationMatrix(rotMat);
	vec = rotMat * vec;
	light.setDirection(vec);
	light.setPosition(position);

	//m_Lights.push_back(pLight);
	m_SceneLights.push_back(light);

	if (m_ShowEntitiesBBox)
	{
		Entity *entity = m_OgreEngine.m_pCurrentSceneManager->createEntity(name, "light.mesh");
		SceneNode *node = m_pSceneNode->createChildSceneNode(name);
		node->setPosition(light.getPosition());
		node->rotate(rot);
		node->scale(10, 10, 10);
		node->attachObject(entity);
	}
}

bool CSceneRencontre :: frameStarted(const FrameEvent& evt)
{
	CSceneBase::frameStarted(evt);


	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_Z) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_RE_StartAnim, 3.0f);
	} 
	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_X) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_RE_StopAnim, 3.0f);
	} 



	if (m_LastTime != -1)
	{
	Real timeElapsed = m_Timer.getSeconds() - m_LastTime;
	if (m_Play)
	{
		m_CamFrame += timeElapsed;
		m_CurrentSpeed = std::min(m_CurrentSpeed + 0.05f, 1.0f);

		m_CloneFrame += timeElapsed * std::min((1.5f - m_CurrentSpeed), 1.0f);
	}
	else
	{
		m_CamFrame += timeElapsed * m_CurrentSpeed;
		m_CurrentSpeed = std::max(m_CurrentSpeed - 0.05f, 0.0f);

		m_CloneFrame += timeElapsed;
	}
	}

	m_LastTime = m_Timer.getSeconds();

	return (true);
}

void CSceneRencontre :: SetCamera(Vector3 const &position, Quaternion const &orientation, bool fake)
{
	if (0 && m_NetConfig == e_NCClientR)
	{
		Entity *nco = findEntity(String("rencontre-clones-nco"));
		if (NULL != nco)
		{
			if (nco->hasSkeleton())
			{
				Bone *head = nco->getSkeleton()->getBone("NCO_Head");
				if (NULL != head)
				{
					Quaternion orientation = head->getWorldOrientation();
					Quaternion rot(Radian(Math::PI), Vector3(0, 1, 0));
					orientation = orientation * rot;
					m_pCurrentCamera->setPosition(head->getWorldPosition());
					m_pCurrentCamera->setOrientation(orientation);
				}
			}
		}
		nco->setMaterialName("openmove/none");
	}
	else
	{
		CSceneBase::SetCamera(position, orientation, fake);
	}
}

void CSceneRencontre :: Attach(void)
{
	CSceneBase::Attach();

	//m_pCurrentCamera->setPosition(-180.8f, 87.7f, 452.3f);
	//m_pCurrentCamera->setDirection(0, 0, -1);
	//m_OgreEngine.m_pViewPort->setBackgroundColour(ColourValue(0, 0, 0, 1.0f));

	//m_OgreEngine.m_pCurrentSceneManager->setShadowFarDistance(1000);
	//m_OgreEngine.m_pCurrentSceneManager->setShadowTextureSize(1024);

	//m_OgreEngine.m_pCurrentSceneManager->setSkyBox(true, "SkyBox/Rencontre");
	m_LastTime = m_Timer.getSeconds();

	m_CamFrame = 0;
	m_CloneFrame = 0;
	m_CurrentSpeed = 0;
}

void CSceneRencontre :: processEvents(void)
{
	CSceneBase::processEvents();

	for (TEvents::iterator It = m_Events.begin(); It != m_Events.end(); ++It)
	{
		switch (It->m_Packet.eventid)
		{
			case SOpenMoveDisplayPacket::e_RE_StartAnim:
			{
				m_Play = true;
				break;
			}
			case SOpenMoveDisplayPacket::e_RE_StopAnim:
			{
				m_Play = false;
				break;
			}
		}
	}

	if (m_NetConfig == e_NCNone || m_NetConfig == e_NCServer)
	{
		Entity *ent = findEntity(String("joint-cam-rencontre"));
		if (NULL != ent && ent->hasSkeleton())
		{
			AnimationState *state = ent->getAnimationState("camera");
			if (NULL != state)
			{
				state->setTimePosition(m_CamFrame);
			}
		}
		
		ent = findEntity(String("rencontre-clones-ana"));
		if (NULL != ent && ent->hasSkeleton())
		{
			AnimationState *state = ent->getAnimationState("danse");
			if (NULL != state)
			{
				state->setTimePosition(m_CloneFrame);
			}
		}
		ent = findEntity(String("rencontre-clones-nco"));
		if (NULL != ent && ent->hasSkeleton())
		{
			AnimationState *state = ent->getAnimationState("danse");
			if (NULL != state)
			{
				state->setTimePosition(m_CloneFrame);
			}
		}
	}
}